/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package server.negocio;


import server.excepciones.BeneficiarioNoExistenteException;
import server.excepciones.MedicoInexistenteException;
import server.excepciones.UsuarioNoExistenteException;
import server.excepciones.UsuarioYaExistenteException;
import cliente.comunicacion.ICliente;
import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;
import java.rmi.RemoteException;
import java.sql.SQLException;
import java.util.ArrayList;
import server.dominio.Beneficiario;
import server.dominio.Medico;
import server.dominio.Usuario;
import server.excepciones.BeneficiarioInexistenteException;
import server.excepciones.BeneficiarioYaExistenteException;
import server.excepciones.MedicoNoExistenteException;
import server.excepciones.MedicoYaExistenteException;
import server.excepciones.ProblemaConexionException;
import server.excepciones.UsuarioIncorrectoException;
import server.senders.Sender_datos;
import server.senders.Sender_lista;

/**
 *
 * @author tpaxle
 */
public class Controlador_G_Usuarios {
    private Fachada_Servidor fachada_basedats;
    private Controlador_Servidor c_servidor;
    private Notificador notificador;

    public Controlador_G_Usuarios(Controlador_Servidor c_servidor){
            //Lee su Configuracion
            fachada_basedats= new Fachada_Servidor();
            this.c_servidor= c_servidor;
            notificador= new Notificador(c_servidor);
    }

  

    private Medico getmedico() throws SQLException{
        //Dependiendo de las opciones devolver un tipo de medico u otro
        return (Medico) fachada_basedats.getMedicos().get(0);
    }

   

    
    public Beneficiario obtenerBeneficiario(long idSesion, String dni) throws UsuarioIncorrectoException, SQLException, BeneficiarioInexistenteException {
        Beneficiario beneficiario = null;
        if(c_servidor.comprobarUsuario(1, idSesion)){
            beneficiario= fachada_basedats.getBeneficiario(dni);
        }
        return beneficiario;
    }
    public Beneficiario obtenerBeneficiarionss(long idSesion, String nss) throws UsuarioIncorrectoException, SQLException, BeneficiarioInexistenteException {
        Beneficiario beneficiario = null;
        if(c_servidor.comprobarUsuario(1, idSesion)){
            beneficiario= fachada_basedats.getBeneficiarionss(nss);
        }
        return beneficiario;
    }
    public Medico obtenerMedico(long idSesion, String dni) throws UsuarioIncorrectoException, SQLException, MedicoNoExistenteException, MedicoInexistenteException {
        Medico medico = null;
        int tiporol= c_servidor.getipousuario(idSesion);
        String login= "";
        //En caso de ser una consulta de administrador o citador devolver un medico
        if(tiporol ==1 || tiporol == 2){
            if(c_servidor.comprobarUsuario(1, idSesion) || c_servidor.comprobarUsuario(2, idSesion)){
                medico= fachada_basedats.getMedico(dni);
            }
        }else{
            //buscamos el usuario y vemos si esta pidiendo sus citas
            login= c_servidor.getlogin(idSesion);
            if(!login.equals("")){
                medico= fachada_basedats.getMedicologin(login);
                if(medico==null){
                    throw new MedicoInexistenteException("El medico con usuario "+ login + "no existe");
                }
            }else{
                throw new UsuarioIncorrectoException("El dni introducido no corresponde con el solicitado");
            }
        }
        
        return medico;
    }
    public void obtenerDatosTablas(long idSesion) throws SQLException, UsuarioIncorrectoException, RemoteException{
        ArrayList<Object> usuarios;
        ArrayList<Object> beneficiarios;
        if(c_servidor.comprobarUsuario(1, idSesion)){
            usuarios= fachada_basedats.getUsuarios();
            beneficiarios= fachada_basedats.getBeneficiarios();
            ICliente cliente= c_servidor.getCliente(idSesion);


            //            //Aqui ejecutamos una nueva tarea para comunicarse con el cliente y le envia la tabla
            Sender_datos sender= new Sender_datos(cliente, usuarios, beneficiarios);
            sender.start();
        }
    }
    public void obtenerDatosCentro(long idSesion) throws SQLException, UsuarioIncorrectoException {
        ArrayList<Object> centros;
        if(c_servidor.comprobarUsuario(1, idSesion)){
            centros= fachada_basedats.getCentros();
            ICliente cliente= c_servidor.getCliente(idSesion);

            Sender_lista sender= new Sender_lista(cliente, centros, 3);
            sender.start();
        }
    }
    public void obtenerDatosMedicos(long idSesion, Object informacion) throws UsuarioIncorrectoException, SQLException {
        //Informacin es un entero
        ArrayList<Object> medicos;
        if(c_servidor.comprobarUsuario(1, idSesion)){
            medicos= fachada_basedats.getMedicos();
            ICliente cliente= c_servidor.getCliente(idSesion);

            Sender_lista sender= new Sender_lista(cliente, medicos, 1);
            sender.start();
        }
    }





 /*Insercion de Usuarios*/
    /******************************************************************/
    /*Insercion Beneficiario*/
    public void crearbeneficiario(long idSesion, Beneficiario beneficiario) throws UsuarioIncorrectoException, SQLException, BeneficiarioYaExistenteException, ProblemaConexionException, Exception {
        if(c_servidor.comprobarUsuario(1, idSesion)){
            //Se pasa al servidor de respaldo
            if(c_servidor.getProxyServidorb().insertarBeneficiario(beneficiario)){
                fachada_basedats.nuevobeneficiario(beneficiario);
                notificador.notificar(4, beneficiario);
            }else{
                throw new ProblemaConexionException("Error en el establecimiento de la conexion con el servidor de respaldo: Crear Beneficiario: "+ beneficiario);
            }
        }
    }

    /*Insercion de Medicos*/
    public void crearmedico(long idSesion, Medico medico) throws SQLException, UsuarioIncorrectoException, UsuarioYaExistenteException, MedicoYaExistenteException, RemoteException, Exception{
        //Comprueba si el de la sesion idSesion es administrador y el login que le hemos pasao es correcto(No existe)
        if(c_servidor.comprobarUsuario(1, idSesion)){
            //Ahora comprobamos que el login, nif es correcto, si se intenta insertar pero hay un constraintviolationexception ya hay algun otro
            if(c_servidor.getProxyServidorb().insertarMedico(medico)){
                fachada_basedats.nuevousuario(medico.getUsuario());
                fachada_basedats.nuevomedico(medico);
                notificador.notificar(1, medico.getUsuario());
            }else{
                throw new ProblemaConexionException("Problema de conexion con la bbdd crearmedico");
            }
        }
    }
    /*Fin Insercion Beneficiario*/
    public void crearUsuario(long idSesion, Object usuario) throws UsuarioIncorrectoException, UsuarioYaExistenteException, SQLException, Exception {
        Usuario usuario_aux= (Usuario)usuario;
        if(c_servidor.comprobarUsuario(1, idSesion)){
            if(c_servidor.getProxyServidorb().insertarUsuario(usuario)){
                fachada_basedats.nuevousuario((Usuario)usuario_aux);
                notificador.notificar(1, usuario_aux);
            }
            else{
                throw new ProblemaConexionException("Problema de conexion con la bbdd de respaldo");
            }
        }
    }

    /*Modificacion de un Usuario normal, si es normal y pasa a normal, se modifica,
     * si pasa a ser medico, se inserta el nuevo medico
     */
    public void modificarUsuario(long idSesion, Object informacion) throws UsuarioIncorrectoException, SQLException, UsuarioYaExistenteException, Exception {
        Usuario usuario_aux=(Usuario)informacion;
        try{
        if(c_servidor.comprobarUsuario(1, idSesion)){
            if (c_servidor.getProxyServidorb().modificarUsuario(usuario_aux)) {
                fachada_basedats.modificarUsuario(usuario_aux);
                if (usuario_aux.getDescripcionrol().getIdRolPk() == 3) {
                    Medico medico_aux = (Medico) informacion;

                    fachada_basedats.nuevomedico(medico_aux);
                    notificador.notificar(3, medico_aux);
                }else
                    notificador.notificar(3, usuario_aux);

            }else{
                throw new ProblemaConexionException("Problema de conexion con la base de datos: Modificar Usuario");
            }

        }
        }catch(MySQLIntegrityConstraintViolationException ex){
            notificador.notificar(12, usuario_aux, idSesion);
        }
    }
    /*Modificacion de un medico, un medico deja de serlo, por lo tanto, queda una fila medico perdida que debe capturarse y eliminarse*/
    public void modificarUsuarioM(long idSesion, Object informacion) throws UsuarioIncorrectoException, SQLException, MedicoYaExistenteException, Exception{
        Usuario usuario_aux=(Usuario)informacion;
        if(c_servidor.comprobarUsuario(1, idSesion)){
            if (c_servidor.getProxyServidorb().modificarUsuarioM(usuario_aux)) {
                fachada_basedats.modificarUsuario(usuario_aux);
                Medico medico = fachada_basedats.comprobarmedicoperdido((Medico) informacion);
                if (medico.getUsuario().getDescripcionrol().getIdRolPk() != 3 && medico != null) {
                    fachada_basedats.eliminarmedico(medico);
                    notificador.notificar(3, medico);
                }else{
                    notificador.notificar(3, usuario_aux);
                }
            }


        }
    }

    public void modificarBeneficiario(long idSesion, Beneficiario beneficiario) throws UsuarioIncorrectoException, SQLException, BeneficiarioYaExistenteException, BeneficiarioNoExistenteException, ProblemaConexionException, Exception {
          if(c_servidor.comprobarUsuario(1, idSesion)){
              if (c_servidor.getProxyServidorb().modificar(beneficiario)) {
                    fachada_basedats.actualizar(beneficiario);
                    notificador.notificar(6, beneficiario);
              }else{
                   throw new ProblemaConexionException("Error en el establecimiento de la conexion con el servidor de respaldo: Modificar Beneficiario: "+ beneficiario);
              }
            
          }
    }

    /*elmina un beneficiario*/
    public void eliminarbeneficiario(long idSesion, Beneficiario beneficiario) throws UsuarioIncorrectoException, SQLException, BeneficiarioNoExistenteException, ProblemaConexionException, Exception {
        if(c_servidor.comprobarUsuario(1, idSesion)){

            if (c_servidor.getProxyServidorb().borrarBeneficiario(beneficiario)) {
                fachada_basedats.eliminarbeneficiario(beneficiario);
                notificador.notificar(5, beneficiario);
            }else{
               throw new ProblemaConexionException("Error en el establecimiento de la conexion con el servidor de respaldo: Eliminar Beneficiario: "+ beneficiario);
            }

           
        }
    }

    public void eliminarmedico(long idSesion, Medico medico) throws UsuarioIncorrectoException, SQLException, UsuarioNoExistenteException, MedicoNoExistenteException, ProblemaConexionException, Exception {
        Usuario usuario_aux= medico.getUsuario();
        boolean ok=true;
        if(c_servidor.comprobarUsuario(1, idSesion)){
            if (c_servidor.getProxyServidorb().borrarMedico(medico)) {
                try{
                    fachada_basedats.eliminarusuario(usuario_aux);
                } catch(MySQLIntegrityConstraintViolationException ex){
                    //El dato no se puede borrar
                    ok= false;
                }
                if(ok)
                    notificador.notificar(2, medico.getUsuario());
                else
                    notificador.notificar(11, medico.getUsuario(), idSesion);
            }else{
                throw new ProblemaConexionException("Error en la conexion con la bbdd: Error eliminacion medico "+ medico);
            }

            

            //Actualizar todos los beneficiarios automaticamente
            //Mandar a los administradores la eliminacion de este usuario
        }
    }
    
    public void borrarUsuario(long idSesion, Object informacion) throws UsuarioIncorrectoException, UsuarioNoExistenteException, SQLException, Exception{
        Usuario usuario_aux= (Usuario)informacion;
        if(c_servidor.comprobarUsuario(1, idSesion)){
    
            if (c_servidor.getProxyServidorb().borrarUsuario(usuario_aux)) {
                fachada_basedats.eliminarusuario(usuario_aux);
                //Mandar a los administradores la eliminacion de este usuario
                notificador.notificar(2, usuario_aux);
            }else{
                throw new ProblemaConexionException("Error con la conexion a la bbdd: errorborrarUsuario"+ usuario_aux);
            }
            //Mandar a los administradores la eliminacion de este usuario




            //Mandar a los administradores la eliminacion de este usuario
        }
    }

    public void modificarMedico(long idSesion, Medico medico) throws UsuarioIncorrectoException, SQLException, MedicoYaExistenteException, UsuarioNoExistenteException, Exception  {
      if(c_servidor.comprobarUsuario(1, idSesion)){

           if (c_servidor.getProxyServidorb().modificar(medico)) {
                fachada_basedats.actualizar(medico);
                //Comprobamos si era medico y ha dejado de serlo
                notificador.notificar(3, medico);
            }else{
                throw new ProblemaConexionException("Error con la conexion con el servidor: modificarMedico: "+ medico);
            }


          }
    }



}
